﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using FileSystem.Models;
using FileSystem.Services.IServices;
using FileSystem.ViewModels;

namespace FileSystem.Services.Realization {
    /// <summary>
    /// 系统接口实现
    /// </summary>
    public class System : ISystem {
        // ******** 公开变量

        // ******** 私有变量

        private IUserStorage _userStorage;
        private IRootDirItemStorage _rootDirItemStorage;
        private IDirItemStorage _dirItemStorage;
        private IPhysicalDiskBlockStorage _physicalDiskBlockStorage;
        private IDiskBlockStorage _diskBlockStorage;
        private IAccessControlInfoStorage _accessControlInfoStorage;

        // ******** 继承方法

        /// <summary>
        /// 获取当前用户
        /// </summary>
        public async Task<User> GetCurrentUser() {
            return UsersPageViewModel.CurrentUser;
        }

        /// <summary>
        /// 获取当前路径
        /// </summary>
        public async Task<string> GetCurrentLocation() {
            return FileSystemPageViewModel.CurrentAddress;
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="userType">用户类型</param>
        /// <param name="image">图片</param>
        /// <param name="description">描述</param>
        public async Task CreateUser(string userName, string password,
            UserConst.UserType userType, string image, string description) {
            /*
             * 业务逻辑：
             * 在用户表添加一行、在根目录项表添加一行、在目录项表添加一行
             */
            var user = new User {
                UserName = userName,
                Password = password,
                Authority = (int) userType,
                Image = image,
                Description = description
            };
            await _userStorage.AddAsync(user);

            var rootDirItem = new RootDirItem {
                UserName = userName, DirItemName = userName + ":"
            };
            await _rootDirItemStorage.AddAsync(rootDirItem);

            var dirItem = new DirItem {
                DirItemName = userName + ":",
                Identifier = "文件标识符",
                DirItemType = DirItem.FolderConst,
                Location = userName + ":\\",
                Size = 0,
                FolderContent = "",
                IsRootDirItem = true
            };
            await _dirItemStorage.AddAsync(dirItem);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        public async Task<bool> Login(string userName, string password) {
            var user = await _userStorage.GetUser(userName);
            if (user.Password == password)
                return true;
            else
                return false;

            return true;
        }

        /// <summary>
        /// 登出
        /// </summary>
        public async Task Logout() {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 格式化(需要先判断当前用户有无权限)
        /// </summary>
        public async Task Format() {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 创建文件夹或纸张
        /// </summary>
        /// <param name="dirItemName">目录项名称</param>
        /// <param name="dirItemType">目录项类型</param>
        /// <param name="size">目录项大小</param>
        public async Task<bool> Create(string dirItemName,
            DirItemConst.Type dirItemType, int size) {
            //调用string getCurrentLocation();获取当前路径
            var currentLocation = await GetCurrentLocation();

            //判断大小是否足够
            var nullBlockNumber = 0;
            var firstNullBlock =
                (await _diskBlockStorage.GetFirstNullDiskBlock())
                .PhysicalBlockNumber;
            var lastNullBlock = (await _diskBlockStorage.GetLastNullDiskBlock())
                .PhysicalBlockNumber;
            var tempDisk = await _diskBlockStorage.GetFirstNullDiskBlock();
            var currentBlock = tempDisk.PhysicalBlockNumber;
            while (true) {
                if (currentBlock == lastNullBlock) {
                    nullBlockNumber++;
                    break;
                }

                tempDisk =
                    await _diskBlockStorage.GetDiskBlock(tempDisk.NextOne);
                currentBlock = tempDisk.PhysicalBlockNumber;
                nullBlockNumber++;
            }

            if (nullBlockNumber * 1024 < size)
                return false;

            //填写部分目录表表项
            var newDirItem = new DirItem();
            newDirItem.DirItemName = dirItemName;
            newDirItem.Location = currentLocation;
            if (dirItemType == DirItemConst.Type.Folder)
                newDirItem.DirItemType = DirItem.FolderConst;
            else
                newDirItem.DirItemType = DirItem.PaperConst;
            newDirItem.Size = size;
            newDirItem.IsRootDirItem = false;

            //对于文件
            if (newDirItem.DirItemType == DirItem.PaperConst) {
                //利用size/(磁盘块大小)计算块数
                var needBlockNumber = size / 1024;
                if (size % 1024 != 0)
                    needBlockNumber++;

                //得到第一块空块物理地址
                //根据已有信息填写添加的表项其余内容(包括物理地址)
                newDirItem.PhysicalBlockAddress = firstNullBlock;
                newDirItem.FolderContent = null;

                //添加目录表表项
                await _dirItemStorage.AddAsync(newDirItem);

                //查找FAT表第一块物理地址，按照表依次查找下一块直到块够了  并更新第一个空闲块的物理地址
                tempDisk = await _diskBlockStorage.GetFirstNullDiskBlock();
                for (var i = 0; i < needBlockNumber; i++) {
                    await _diskBlockStorage.ModifyProperty(tempDisk,
                        DiskBlockConst.Property.PhysicalBlockType,
                        (int) DiskBlockConst.Type.Full);
                    if (i == needBlockNumber - 1)
                        break;
                    tempDisk =
                        await _diskBlockStorage.GetDiskBlock(tempDisk.NextOne);
                }

                if (tempDisk != null) {
                    DiskBlockConst.First = tempDisk.NextOne;
                    await _diskBlockStorage.ModifyProperty(tempDisk,
                        DiskBlockConst.Property.NextOne, -1);
                }

                //判断是否是管理员
                var currentUser = (await GetCurrentUser()).UserName;

                //是管理员
                if (currentUser == "Administrator") {
                    //新增对应文件的权限表 把管理员加入
                    var newAccessControlInfo = new AccessControlInfo();
                    newAccessControlInfo.DirItemName = dirItemName;
                    newAccessControlInfo.Location = currentLocation;
                    newAccessControlInfo.UserName = "Administrator";
                    newAccessControlInfo.Readable = true;
                    newAccessControlInfo.Writable = true;
                    newAccessControlInfo.Deletable = true;
                    await _accessControlInfoStorage.AddAsync(
                        newAccessControlInfo);

                    //获取用户列表.
                    var userList = await _userStorage.GetUsers();
                    string otherUserLocation;

                    //把用户都加进权限表
                    for (var i = 1; i < userList.Count; i++) {
                        newAccessControlInfo.DirItemName = dirItemName;
                        newAccessControlInfo.Location = currentLocation;
                        newAccessControlInfo.UserName = userList[i].UserName;
                        newAccessControlInfo.Readable = true;
                        newAccessControlInfo.Writable = true;
                        newAccessControlInfo.Deletable = false;
                        await _accessControlInfoStorage.AddAsync(
                            newAccessControlInfo);
                    }

                    //判断是否是根目录
                    if (currentLocation.Equals("Administrator:\\")) //是
                    {
                        //获取用户列表
                        //包括管理员的每一个用户的根目录的foldContent添加这个文件
                        var tempDirItem = new DirItem();
                        string tempFolderContent;
                        var tempInt2String = "";
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                "Administrator:", "Administrator:");
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;

                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);

                        for (var i = 1; i < userList.Count; i++) {
                            tempInt2String = "";
                            otherUserLocation =
                                currentLocation.Replace("Administrator",
                                    userList[i].UserName);
                            tempDirItem =
                                await _dirItemStorage.GetDirItemAsync(
                                    userList[i].UserName + ":",
                                    userList[i].UserName + ":");
                            tempFolderContent = tempDirItem.FolderContent;
                            tempInt2String += newDirItem.Id.ToString();
                            if (tempFolderContent != null)
                                tempFolderContent = tempFolderContent + "," +
                                    tempInt2String;
                            else
                                tempFolderContent = tempInt2String;
                            await _dirItemStorage.ModifyProperty(tempDirItem,
                                DirItemConst.Property.FolderContent,
                                tempFolderContent);
                        }
                    }
                    //不是 给当前目录更新foldContent
                    else {
                        string tempFolderContent;
                        string[] dirLocation;
                        string dirName;
                        var tempInt2String = "";
                        var tempDirItem = new DirItem();
                        dirLocation = currentLocation.Split('\\'); //以'\'分割路径
                        dirName =
                            dirLocation[dirLocation.Length - 1]; //最后一部分就是当前目录名称
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                currentLocation.Replace(dirName, ""),
                                dirName); //把路径当前目录名称去掉得到当前目录路径
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                    }
                }
                //是普通用户
                else {
                    //新增对应文件的权限表 把自己加进去
                    var newAccessControlInfo = new AccessControlInfo();
                    newAccessControlInfo.DirItemName = dirItemName;
                    newAccessControlInfo.Location = currentLocation;
                    newAccessControlInfo.UserName =
                        (await GetCurrentUser()).UserName;
                    newAccessControlInfo.Readable = true;
                    newAccessControlInfo.Writable = true;
                    newAccessControlInfo.Deletable = true;
                    await _accessControlInfoStorage.AddAsync(
                        newAccessControlInfo);

                    //把管理员加进权限表
                    newAccessControlInfo.DirItemName = dirItemName;
                    newAccessControlInfo.Location = currentLocation;
                    newAccessControlInfo.UserName = "Administrator";
                    newAccessControlInfo.Readable = true;
                    newAccessControlInfo.Writable = true;
                    newAccessControlInfo.Deletable = true;
                    await _accessControlInfoStorage.AddAsync(
                        newAccessControlInfo);

                    //判断是否是根目录
                    if (currentLocation.Equals(
                        (await GetCurrentUser()).UserName + ":\\")) //是
                    {
                        //自己和管理员的对应目录的foldContent添加这个文件
                        var tempDirItem = new DirItem();
                        var tempFolderContent = "";
                        var tempInt2String = "";
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                (await GetCurrentUser()).UserName + ":",
                                (await GetCurrentUser()).UserName + ":");
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                        tempInt2String = "";
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                "Administrator:", "Administrator:");
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                    }
                    //不是  给当前目录更新foldContent
                    else {
                        string tempFolderContent;
                        string[] dirLocation;
                        string dirName;
                        var tempInt2String = "";
                        var tempDirItem = new DirItem();
                        dirLocation = currentLocation.Split('\\'); //以'\'分割路径
                        dirName =
                            dirLocation[dirLocation.Length - 1]; //最后一部分就是当前目录名称
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                currentLocation.Replace(dirName, ""),
                                dirName); //把路径当前目录名称去掉得到当前目录路径
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                    }
                }
            }
            //对于目录
            else {
                //忽略块数 根据已有信息填写添加的表项内容 “foldContent”这一属性赋值为空字符串 代表空目录
                newDirItem.PhysicalBlockAddress = -1;
                newDirItem.FolderContent = "";
                await _dirItemStorage.AddAsync(newDirItem);

                //判断是否是管理员
                var currentUser = (await GetCurrentUser()).UserName;
                //是管理员
                if (currentUser == "Administrator") {
                    //新增对应目录的权限表 把管理员加入
                    var newAccessControlInfo = new AccessControlInfo();
                    newAccessControlInfo.DirItemName = dirItemName;
                    newAccessControlInfo.Location = currentLocation;
                    newAccessControlInfo.UserName = "Administrator";
                    newAccessControlInfo.Readable = true;
                    newAccessControlInfo.Writable = true;
                    newAccessControlInfo.Deletable = true;
                    await _accessControlInfoStorage.AddAsync(
                        newAccessControlInfo);

                    //获取用户列表.
                    var userList = await _userStorage.GetUsers();
                    string otherUserLocation;

                    //把用户都加进权限表
                    for (var i = 0; i < userList.Count; i++) {
                        newAccessControlInfo.DirItemName = dirItemName;
                        newAccessControlInfo.Location = currentLocation;
                        newAccessControlInfo.UserName = userList[i].UserName;
                        newAccessControlInfo.Readable = true;
                        newAccessControlInfo.Writable = true;
                        newAccessControlInfo.Deletable = false;
                        await _accessControlInfoStorage.AddAsync(
                            newAccessControlInfo);
                    }

                    //判断是否是根目录
                    if (currentLocation.Equals("Administrator:\\")) //是
                    {
                        //获取用户列表
                        //每一个用户的对应目录的foldContent添加这个目录
                        var tempDirItem = new DirItem();
                        string tempFolderContent;
                        var tempInt2String = "";

                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                "Administrator:", "Administrator:");
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;

                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);

                        for (var i = 1; i < userList.Count; i++) {
                            tempInt2String = "";
                            otherUserLocation =
                                currentLocation.Replace("Administrator",
                                    userList[i].UserName);
                            tempDirItem =
                                await _dirItemStorage.GetDirItemAsync(
                                    userList[i].UserName + ":",
                                    userList[i].UserName + ":");
                            tempFolderContent = tempDirItem.FolderContent;
                            tempInt2String += newDirItem.Id.ToString();
                            if (tempFolderContent != null)
                                tempFolderContent = tempFolderContent + "," +
                                    tempInt2String;
                            else
                                tempFolderContent = tempInt2String;
                            await _dirItemStorage.ModifyProperty(tempDirItem,
                                DirItemConst.Property.FolderContent,
                                tempFolderContent);
                        }
                    }
                    //不是 更新上一级文件夹的foldContent
                    else {
                        string tempFolderContent;
                        string[] dirLocation;
                        string dirName;
                        var tempInt2String = "";
                        var tempDirItem = new DirItem();
                        dirLocation = currentLocation.Split('\\'); //以'\'分割路径
                        dirName =
                            dirLocation[dirLocation.Length - 1]; //最后一部分就是当前目录名称
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                currentLocation.Replace(dirName, ""),
                                dirName); //把路径当前目录名称去掉得到当前目录路径
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                    }
                }
                //是普通用户
                else {
                    //新增对应目录的权限表 把自己加进去
                    var newAccessControlInfo = new AccessControlInfo();
                    newAccessControlInfo.DirItemName = dirItemName;
                    newAccessControlInfo.Location = currentLocation;
                    newAccessControlInfo.UserName =
                        (await GetCurrentUser()).UserName;
                    newAccessControlInfo.Readable = true;
                    newAccessControlInfo.Writable = true;
                    newAccessControlInfo.Deletable = true;
                    await _accessControlInfoStorage.AddAsync(
                        newAccessControlInfo);

                    //把管理员加进权限表
                    newAccessControlInfo.DirItemName = dirItemName;
                    newAccessControlInfo.Location = currentLocation;
                    newAccessControlInfo.UserName = "Administrator";
                    newAccessControlInfo.Readable = true;
                    newAccessControlInfo.Writable = true;
                    newAccessControlInfo.Deletable = true;
                    await _accessControlInfoStorage.AddAsync(
                        newAccessControlInfo);

                    //判断是否是在根目录
                    if (currentLocation.Equals(
                        (await GetCurrentUser()).UserName + ":\\")) //是
                    {
                        //自己和管理员的对应目录的foldContent添加这个目录
                        var tempDirItem = new DirItem();
                        var tempFolderContent = "";
                        var tempInt2String = "";
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                (await GetCurrentUser()).UserName + ":",
                                (await GetCurrentUser()).UserName + ":");
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);

                        tempInt2String = "";
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                "Administrator:", "Administrator:");
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                    }
                    //不是  给上一级目录更新foldContent
                    else {
                        string tempFolderContent;
                        string[] dirLocation;
                        string dirName;
                        var tempInt2String = "";
                        var tempDirItem = new DirItem();
                        dirLocation = currentLocation.Split('\\'); //以'\'分割路径
                        dirName =
                            dirLocation[dirLocation.Length - 1]; //最后一部分就是当前目录名称
                        tempDirItem =
                            await _dirItemStorage.GetDirItemAsync(
                                currentLocation.Replace(dirName, ""),
                                dirName); //把路径当前目录名称去掉得到当前目录路径
                        tempFolderContent = tempDirItem.FolderContent;
                        tempInt2String += newDirItem.Id.ToString();
                        if (tempFolderContent != null)
                            tempFolderContent = tempFolderContent + "," +
                                tempInt2String;
                        else
                            tempFolderContent = tempInt2String;
                        await _dirItemStorage.ModifyProperty(tempDirItem,
                            DirItemConst.Property.FolderContent,
                            tempFolderContent);
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// 为单个用户创建文件夹或纸张
        /// </summary>
        /// <param name="dirItemName">目录项名称</param>
        /// <param name="dirItemType">目录项类型</param>
        /// <param name="size">目录项大小</param>
        /// <param name="location">路径</param>
        public async Task CreateForUser(string dirItemName,
            DirItemConst.Type dirItemType, int size, string location) {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 打开目录项
        /// </summary>
        public async Task<IList<DirItem>> Open(string dirItemName,
            DirItemConst.Type dirItemType, string location) {
            IList<DirItem> list = new List<DirItem>();
            if (dirItemType == DirItemConst.Type.Folder) {
                var dirItem =
                    await _dirItemStorage.GetDirItemAsync(location,
                        dirItemName);
                var idStrings = dirItem.FolderContent.Split(',');
                if (idStrings.Length==1&&idStrings[0] == "")
                    return null;

                for (int i = 1; i < idStrings.Length; i++) {
                    var id = int.Parse(idStrings[i]);
                    list.Add(await _dirItemStorage.GetDirItemAsync(id));
                }
            }

            return list;
        }

        /// <summary>
        /// 关闭目录项
        /// </summary>
        public async Task<IList<DirItem>> Close(string location) {
            IList<DirItem> list = new List<DirItem>();
            list = await _dirItemStorage.GetDirItemsAsync(location);
            return list;
        }

        /// <summary>
        /// 读目录项
        /// </summary>
        /// <param name="dirItemName">目录项名称</param>
        /// <param name="location">路径</param>
        /// <param name="dataSize">目录项大小</param>
        public async Task<string> Read(string dirItemName, string location,
            int dataSize) {
            //判断权限：根据文件名和路径检索权限表查看当前用户是否拥有权限
            var currentUser = (await GetCurrentUser()).UserName;
            var tempAccessControlInfo = new AccessControlInfo();
            // tempAccessControlInfo =
            //     await _accessControlInfoStorage.GetAccessControlInfo(
            //         dirItemName, location, currentUser);
            // if (tempAccessControlInfo.Readable == false)
            //     //没有读取权限
            //     return null;

            //根据文件名和路径找到文件第一块的物理地址
            var tempDirItem = new DirItem();
            tempDirItem =
                await _dirItemStorage.GetDirItemAsync(location, dirItemName);
            var fileFirstBlock = tempDirItem.PhysicalBlockAddress;
            var tempBlock = fileFirstBlock;
            var contentReturn = "";

            //根据读的大小确定找到的磁盘块数 
            if (dataSize > tempDirItem.Size)
                dataSize = tempDirItem.Size;
            var BlocksNumber = dataSize / 1024;
            if (dataSize % 1024 != 0)
                BlocksNumber++;

            //循环所有需要的磁盘块 获取内容
            var tempPhysicalDiskBlock = new PhysicalDiskBlock();
            for (var i = 0; i < BlocksNumber - 1; i++) {
                contentReturn +=
                    (await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                        tempBlock)).Content;
                tempBlock = (await _diskBlockStorage.GetDiskBlock(tempBlock))
                    .NextOne;
            }

            //最后一个磁盘不一定读完，故需要另外读取
            var tempString =
                (await _physicalDiskBlockStorage
                    .GetPhysicalDiskBlock(tempBlock)).Content;
            var extraRead = dataSize % 1024;
            for (var i = 0; i < extraRead; i++)
                contentReturn += tempString[i];
            //返回字符串
            return contentReturn;
        }

        /// <summary>
        /// 写目录项
        /// </summary>
        /// <param name="dirItemName">目录项名称</param>
        /// <param name="location">路径</param>
        /// <param name="content">内容</param>
        /// <param name="dataSize">目录项大小</param>
        public async Task<bool> Write(string dirItemName, string location,
            string content, int dataSize) {
            //判断权限：根据文件名和路径检索权限表查看当前用户是否拥有权限
            var currentUser = (await GetCurrentUser()).UserName;
            var tempAccessControlInfo = new AccessControlInfo();
            // tempAccessControlInfo =
            //     await _accessControlInfoStorage.GetAccessControlInfo(
            //         dirItemName, location, currentUser);
            // if (tempAccessControlInfo.Readable == false)
            //     //没有写权限
            //     return false;
            //根据文件名和路径找到文件第一块的物理地址
            var tempDirItem = new DirItem();
            tempDirItem =
                await _dirItemStorage.GetDirItemAsync(location, dirItemName);
            //根据写的大小判断是否超出文件可以写的大小
            var FileBlockNumber = tempDirItem.Size / 1024;
            var nullBlocks = 0;
            if (tempDirItem.Size % 1024 != 0)
                FileBlockNumber++;
            var fileFirstBlock = tempDirItem.PhysicalBlockAddress;
            var tempBlock = fileFirstBlock;
            var FileBlockNotFull = tempBlock;

            for (var i = 0; i < FileBlockNumber; i++) {
                if ((await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                    tempBlock)).Content.Length < 1024) {
                    FileBlockNotFull = tempBlock;
                    nullBlocks = FileBlockNumber - i - 1;
                    break;
                }

                tempBlock = (await _diskBlockStorage.GetDiskBlock(tempBlock))
                    .NextOne;
            }

            if (tempBlock == -1 ||
                    nullBlocks * 1024 + 1024 -
                    (await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                        FileBlockNotFull)).Content.Length <
                    dataSize) //说明直到最后一块文件可写的内容都满了 或者剩下的部分小于需要的部分
                //空间满了 所以写失败 不允许写
                return false;

            var sizeReliable = 1024 -
                (await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                    FileBlockNotFull)).Content.Length;
            var sizeNow =
                (await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                    FileBlockNotFull)).Content.Length;
            var FirstBlockContentPlus = "";
            for (var i = 0; i < dataSize && i < sizeReliable;
                i++) //没有超出，那么开始写文件，取content字符先填满第一个块
                FirstBlockContentPlus += content[i];
            var tempPhysicalDiskBlock = new PhysicalDiskBlock();
            tempPhysicalDiskBlock =
                await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                    FileBlockNotFull);
            await _physicalDiskBlockStorage.ModifyContent(FileBlockNotFull,
                FirstBlockContentPlus);
            //接下来处理其他的部分
            if (dataSize > sizeReliable)
                content = content.Substring(sizeReliable,
                    content.Length - sizeReliable);
            dataSize -= sizeReliable;
            FileBlockNotFull =
                (await _diskBlockStorage.GetDiskBlock(FileBlockNotFull))
                .NextOne;
            string tempString2;
            while (true) {
                tempPhysicalDiskBlock =
                    await _physicalDiskBlockStorage.GetPhysicalDiskBlock(
                        FileBlockNotFull);
                if (dataSize < 0)
                    break;
                if (dataSize >= 1024) {
                    tempString2 = content.Substring(0, 1024);
                    await _physicalDiskBlockStorage.ModifyContent(FileBlockNotFull,
                        tempString2);
                    content = content.Substring(1024, content.Length - 1024);
                    dataSize -= 1024;
                }

                if (dataSize < 1024 && dataSize > 0) {
                    tempString2 = content;
                    await _physicalDiskBlockStorage.ModifyContent(FileBlockNotFull,
                        tempString2);
                    break;
                }

                FileBlockNotFull =
                    (await _diskBlockStorage.GetDiskBlock(FileBlockNotFull))
                    .NextOne;
            }

            return true;
        }

        /// <summary>
        /// 删除目录项
        /// </summary>
        /// <param name="dirItemName">目录项名称</param>
        public async Task<bool> Delete(string dirItemName, string location) {
            var currentLocation = await GetCurrentLocation();
            var tempDirItem = new DirItem();
            //判断权限：根据文件名和路径检索权限表查看当前用户是否拥有权限
            var currentUser = (await GetCurrentUser()).UserName;
            var tempAccessControlInfo = new AccessControlInfo();
            tempAccessControlInfo =
                await _accessControlInfoStorage.GetAccessControlInfo(
                    dirItemName, location, currentUser);
            if (tempAccessControlInfo.Deletable == false)
                return false;
            tempDirItem =
                await _dirItemStorage.GetDirItemAsync(location, dirItemName);
            //如果是文件
            if (tempDirItem.DirItemType.Equals(DirItem.PaperConst)) {
                //调用getLastNullBlock();得到第最后一块物理地址
                var lastNullBlockNumber =
                    (await _diskBlockStorage.GetLastNullDiskBlock())
                    .PhysicalBlockNumber;
                //查找目录表文件的第一个物理块、利用文件大小计算块数
                var fileFirstBlock = tempDirItem.PhysicalBlockAddress;
                var blocksNumber = tempDirItem.Size / 1024;
                if (tempDirItem.Size % 1024 != 0)
                    blocksNumber++;
                //查找最后一块物理地址，给这个物理块地址在表中的“下一块”属性赋值为文件的第一个物理块
                var tempDiskBlock =
                    await _diskBlockStorage.GetLastNullDiskBlock();
                await _diskBlockStorage.ModifyProperty(tempDiskBlock,
                    DiskBlockConst.Property.NextOne, fileFirstBlock);
                //利用文件大小找到文件的最后一个物理块地址，把这个地址在表中的“下一块”属性赋值为特殊值代表末尾
                for (var i = 0; i < blocksNumber; i++) {
                    tempDiskBlock =
                        await _diskBlockStorage.GetDiskBlock(tempDiskBlock
                            .NextOne);
                    await _diskBlockStorage.ModifyProperty(tempDiskBlock,
                        DiskBlockConst.Property.PhysicalBlockType,
                        (int) DiskBlockConst.Type.Null);
                    await _physicalDiskBlockStorage.ModifyContent(
                        tempDiskBlock.PhysicalBlockNumber, "");
                } //循环结束最后一个tempDiskBlock一定对应文件最后一个磁盘块，此时nextOne应该为-1，不需要再赋值代表末尾

                DiskBlockConst.Last = tempDiskBlock.PhysicalBlockNumber;
            }
            //如果是目录
            else {
                //判断目录foldContent是否空
                //不为空 不允许删除
                if (!tempDirItem.FolderContent.Equals(""))
                    return false;
            }

            //更新文件夹的foldContent信息 先判断是否文件夹在根目录

            //不在
            if (!location.Equals((await GetCurrentUser()).UserName + ":\\")) {
                //只需要把文件上一级目录的foldContent更新
                string tempFolderContent;
                string[] dirLocation;
                string dirName;
                var tempInt2String = "";
                string[] tempStrings;
                var newFolderContent = "";
                var tempDirItemForUpdate = new DirItem();
                dirLocation = location.Split('\\'); //以'\'分割路径
                dirName = dirLocation[dirLocation.Length - 1]; //最后一部分就是当前目录名称
                tempDirItemForUpdate =
                    await _dirItemStorage.GetDirItemAsync(
                        location.Replace(dirName, ""),
                        dirName); //把路径当前目录名称去掉得到当前目录路径
                tempFolderContent = tempDirItemForUpdate.FolderContent;
                tempStrings = tempFolderContent.Split(','); //以','分割文件夹内容路径
                var item = await _dirItemStorage.GetDirItemAsync(location,
                    dirItemName);
                tempInt2String = item.Id.ToString();
                for (var i = 0; i < tempStrings.Length; i++) {
                    if (tempStrings[i].Equals(tempInt2String))
                        continue;
                    newFolderContent += tempStrings[i].ToString();
                    newFolderContent += ",";
                }

                if (newFolderContent.Length > 1)
                    newFolderContent =
                        newFolderContent.Substring(0,
                            newFolderContent.Length - 1); //删除在最后的','
                await _dirItemStorage.ModifyProperty(tempDirItemForUpdate,
                    DirItemConst.Property.FolderContent, newFolderContent);
            }
            //在
            else {
                //如果是管理员，则更新自己根目录和所有用户根目录的foldContent
                if ((await GetCurrentUser()).UserName.Equals("Administrator")) {
                    var tempDirItemForUpdate = new DirItem();
                    string tempFolderContent;
                    string[] tempStrings;
                    var tempInt2String = "";
                    var newFolderContent = "";
                    var userList = await _userStorage.GetUsers();
                    tempDirItemForUpdate =
                        await _dirItemStorage.GetDirItemAsync("Administrator:",
                            "Administrator:");
                    tempFolderContent = tempDirItemForUpdate.FolderContent;
                    tempStrings = tempFolderContent.Split(','); //以','分割文件夹内容路径
                    var item = await _dirItemStorage.GetDirItemAsync(location,
                        dirItemName);
                    tempInt2String = item.Id.ToString();
                    for (var i = 0; i < tempStrings.Length; i++) {
                        if (tempStrings[i].Equals(tempInt2String))
                            continue;
                        newFolderContent += tempStrings[i].ToString();
                        newFolderContent += ",";
                    }

                    if (newFolderContent.Length > 1)
                        newFolderContent =
                            newFolderContent.Substring(0,
                                newFolderContent.Length - 1); //删除在最后的','
                    await _dirItemStorage.ModifyProperty(tempDirItemForUpdate,
                        DirItemConst.Property.FolderContent, newFolderContent);

                    string otherUserLocation;
                    for (var i = 1; i < userList.Count; i++) {
                        otherUserLocation =
                            currentLocation.Replace("Administrator",
                                userList[i].UserName);
                        tempDirItemForUpdate =
                            await _dirItemStorage.GetDirItemAsync(
                                userList[i].UserName + ":",
                                userList[i].UserName + ":");
                        tempFolderContent = tempDirItemForUpdate.FolderContent;
                        tempStrings =
                            tempFolderContent.Split(','); //以','分割文件夹内容路径
                        tempInt2String = tempDirItemForUpdate.Id.ToString();
                        for (var j = 0; j < tempStrings.Length; j++) {
                            if (tempStrings[j].Equals(tempInt2String))
                                continue;
                            newFolderContent += tempStrings[j].ToString();
                            newFolderContent += ",";
                        }

                        if (newFolderContent.Length > 1)
                            newFolderContent =
                                newFolderContent.Substring(0,
                                    newFolderContent.Length - 1); //删除在最后的','
                        tempInt2String += tempDirItemForUpdate.Id.ToString();
                        tempFolderContent =
                            tempFolderContent + "," + tempInt2String;
                        await _dirItemStorage.ModifyProperty(
                            tempDirItemForUpdate,
                            DirItemConst.Property.FolderContent,
                            newFolderContent);
                    }
                }
                //如果是普通用户，则更新自己根目录和管理员根目录的foldContent
                else {
                    //自己和管理员的对应目录的foldContent添加这个文件
                    string tempFolderContent;
                    string[] dirLocation;
                    string dirName;
                    var tempInt2String = "";
                    string[] tempStrings;
                    var newFolderContent = "";
                    var tempDirItemForUpdate = new DirItem();

                    tempDirItemForUpdate =
                        await _dirItemStorage.GetDirItemAsync(
                            (await GetCurrentUser()).UserName + ":",
                            (await GetCurrentUser()).UserName + ":");
                    tempFolderContent = tempDirItemForUpdate.FolderContent;
                    tempStrings = tempFolderContent.Split(','); //以','分割文件夹内容路径
                    var item = await _dirItemStorage.GetDirItemAsync(location,
                        dirItemName);
                    tempInt2String = item.Id.ToString();
                    for (var i = 0; i < tempStrings.Length; i++) {
                        if (tempStrings[i].Equals(tempInt2String))
                            continue;
                        newFolderContent += tempStrings[i].ToString();
                        newFolderContent += ",";
                    }

                    if (newFolderContent.Length > 1)
                        newFolderContent =
                            newFolderContent.Substring(0,
                                newFolderContent.Length - 1); //删除在最后的','
                    await _dirItemStorage.ModifyProperty(tempDirItemForUpdate,
                        DirItemConst.Property.FolderContent, newFolderContent);

                    tempDirItemForUpdate =
                        await _dirItemStorage.GetDirItemAsync("Administrator:",
                            "Administrator:");
                    tempFolderContent = tempDirItemForUpdate.FolderContent;
                    item = await _dirItemStorage.GetDirItemAsync(location,
                        dirItemName);
                    tempInt2String = item.Id.ToString();
                    for (var i = 0; i < tempStrings.Length; i++) {
                        if (tempStrings[i].Equals(tempInt2String))
                            continue;
                        newFolderContent += tempStrings[i].ToString();
                        newFolderContent += ",";
                    }

                    if (newFolderContent.Length > 1)
                        newFolderContent =
                            newFolderContent.Substring(0,
                                newFolderContent.Length - 1); //删除在最后的','
                    await _dirItemStorage.ModifyProperty(tempDirItemForUpdate,
                        DirItemConst.Property.FolderContent, newFolderContent);
                }
            }

            //删除文件对应的权限表
            var tempAceessControlInfo = new AccessControlInfo();
            var userList1 = await _userStorage.GetUsers();
            for (var i = 0; i < userList1.Count; i++) {
                tempAceessControlInfo =
                    await _accessControlInfoStorage.GetAccessControlInfo(
                        dirItemName, location, userList1[i].UserName);
                if (tempAceessControlInfo != null)
                    await _accessControlInfoStorage.RemoveAsync(
                        tempAceessControlInfo);
            }

            //删除记录
            await _dirItemStorage.RemoveAsync(tempDirItem);

            return true;
        }

        /// <summary>
        /// 为单个用户删除目录项
        /// </summary>
        /// <param name="dirItemName">目录项名称</param>
        /// <param name="location">路径</param>
        /// <param name="dirItemType">目录项类型</param>
        public async Task DeleteForUser(string dirItemName, string location,
            DirItemConst.Type dirItemType) {
            throw new NotImplementedException();
        }

        // ******** 公开方法
        public System(IUserStorage userStorage,
            IRootDirItemStorage rootDirItemStorage,
            IDirItemStorage dirItemStorage,
            IPhysicalDiskBlockStorage physicalDiskBlockStorage,
            IDiskBlockStorage diskBlockStorage,
            IAccessControlInfoStorage accessControlInfoStorage) {
            {
                _userStorage = userStorage;
                _rootDirItemStorage = rootDirItemStorage;
                _dirItemStorage = dirItemStorage;
                _physicalDiskBlockStorage = physicalDiskBlockStorage;
                _diskBlockStorage = diskBlockStorage;
                _accessControlInfoStorage = accessControlInfoStorage;
            }
        }

        // ******** 私有方法
    }
}